#![allow(non_snake_case)]
use std::collections::HashMap;

use crate::{
    DrawerBody, DrawerHeader, DrawerHeaderTitle, DrawerHeaderTitleAction, DrawerPosition,
    MultiTreeSelect, OverlayDrawer, TableState, TreeItems,
};
use icondata as i;
use leptos::prelude::*;
use leptos_icons::*;
use shq_common::prelude::{ColumnCells, ContextMenus, DataType};

use crate::table::order_filter::{ColumnFilter, ColumnOrder};
#[component]
pub fn OrderFilterModel(
    ///表格列头
    #[prop(into)]
    header_cells: Memo<ColumnCells>,
    ///选项map
    #[prop(into)]
    opts_map: Memo<HashMap<String, StoredValue<TreeItems>>>,
) -> impl IntoView {
    let table_state =
        use_context::<ReadSignal<TableState>>().expect("ReadSignal<TableState>上下文不存在");
    let context_menus = use_context::<StoredValue<ContextMenus>>();
    let sel_col = table_state.with_untracked(|ts| ts.selected_col());
    let page = table_state.with_untracked(|ts| ts.page().write_only());
    let column_data = Memo::new(move |_| {
        sel_col.with(|col| {
            col.as_ref().map(|(col_name, _)| {
                let col_str = col_name.as_str();
                table_state.with_untracked(|ts| {
                    let order = ts.order(col_str);
                    let filter = ts.filter(col_str);
                    let cell_info = header_cells.with(|hcs| {
                        hcs.get_leaf_cell_by_name(col_str).map(|cell| {
                            let dt = if cell.dict_col_name.is_some() {
                                DataType::String
                            } else {
                                cell.data_type
                            };
                            (cell.title.clone(), dt, cell.is_null)
                        })
                    });
                    (col_name.clone(), cell_info, order, filter)
                })
            })
        })
    });
    // 视图渲染
    let render_dialog = move || {
        if let Some(column_info) = column_data.get() {
            let (col_name, label_type, order, filter) = column_info;
            let label = label_type.as_ref().map(|(l, _, _)| l.clone());
            let (data_type, is_null) = label_type
                .clone()
                .map(|(_, dt, is_null)| (dt.clone(), is_null))
                .unwrap_or((DataType::String, false));
            let tree_items = opts_map.with(|m| m.get(&col_name).cloned().map(|items| items));
            let context_menu_view = if let Some(context_menus) = context_menus {
                let menus = context_menus.with_value(|cm| cm.get_col_context_menu_list(&col_name));
                Some(view! {
                    <div class="divider">"分析"</div>
                    <ul class="menu menu-horizontal bg-base-200 rounded-box">
                        {
                            menus.into_iter().map(|(idx, label)| view!{
                                <li>
                                    <a on:click=move |ev| {
                                        ev.prevent_default();
                                        ev.stop_propagation();
                                        // 执行对应的操作
                                        table_state.with_untracked(|ts|{
                                            ts.context_action_index.set(Some(idx));
                                        });
                                        // 关闭对话框
                                        sel_col.update(|col|{ col.as_mut().map(|(_,show)|*show=false); });
                                    }>{label}</a>
                                </li>
                            }).collect_view()
                        }
                    </ul>
                })
            } else {
                None
            };
            either_of::Either::Left(view! {
                <dialog class="modal modal-open">
                    <div class="modal-box">
                        <header class="flex justify-between items-center">
                            <h3 class="text-lg font-bold">{label}</h3>
                            <button class="btn btn-sm btn-circle"
                                    on:click=move |_| sel_col.update(|col|{ col.as_mut().map(|(_,show)|*show=false); })>
                                <Icon icon=i::AiCloseCircleOutlined/>
                            </button>
                        </header>
                        <div class="card-body">
                            // 排序组件
                            {move || order.as_ref().map(|order_signal| {
                                view! { <ColumnOrder order_signal=order_signal.clone() sel_col=sel_col.write_only()/> }
                            })}
                            // 过滤器组件
                            {move || filter.as_ref().map(|filter_signal| {
                               view! { <ColumnFilter filters=filter_signal.clone()
                                        column_name=Oco::from(col_name.clone())
                                        data_type=data_type
                                        can_null=is_null
                                        sel_col=sel_col.write_only()
                                        tree_items=tree_items
                                        page/>}
                            })}
                            // 上下文菜单组件
                            {context_menu_view}
                        </div>
                    </div>
                </dialog>
            })
        } else {
            either_of::Either::Right(view! { <></> })
        }
    };
    log::info!("sel_col changed:{:?}", sel_col.get());
    // 直接返回条件渲染结果，不使用 Show 组件
    move || {
        if sel_col.with(|sc| sc.as_ref().map(|sc| sc.1).unwrap_or(false)) {
            either_of::Either::Left(render_dialog())
        } else {
            either_of::Either::Right(view! { <></> })
        }
    }
}

#[component]
pub fn ColumnShows(
    /// 要显示的列
    #[prop(into)]
    tree_items: StoredValue<TreeItems>,
) -> impl IntoView {
    let table_state =
        use_context::<ReadSignal<TableState>>().expect("ReadSignal<TableState>在上下文中不存在");
    let show_drawer = table_state.with_untracked(|ts| ts.show_sel_cols_drawer());
    let display_cols: ReadSignal<Vec<String>> = table_state.with_untracked(|ts| ts.display());
    // let icon_map = Memo::new(move |_| {
    //     display_cols.with(|cols| {
    //         cols.iter()
    //             .map(|k| table_state.with_untracked(|ts| (k.clone(), ts.get_icon(k))))
    //             .collect::<HashMap<_, _>>()
    //     })
    // });
    let on_confirm = move |selected_cols: Vec<String>| {
        table_state.with_untracked(|ts| {
            ts.set_display(selected_cols);
            ts.show_sel_cols_drawer().set(false);
        });
    };
    let on_cancel = move |()| {
        table_state.with_untracked(|ts| {
            ts.show_sel_cols_drawer().set(false);
        });
    };
    view! {
        <OverlayDrawer open=show_drawer position=DrawerPosition::Right class="bg-base-100">
            <DrawerHeader>
                <DrawerHeaderTitle>
                    <DrawerHeaderTitleAction slot>
                        <button class="btn btn-ghost" on:click=move |_| show_drawer.set(false)>
                            <Icon icon=i::AiCloseCircleOutlined/>
                        </button>
                    </DrawerHeaderTitleAction>
                    <p class="mx-2">"选择列"</p>
                </DrawerHeaderTitle>
            </DrawerHeader>
            <DrawerBody>
                <div class="h-screen w-full overflow-hidden">
                    <MultiTreeSelect tree_items values=display_cols.get_untracked() can_filter=true checked_item_read_only=display_cols.with_untracked(|cols|cols.len()==1) on_confirm on_cancel/>
                </div>
            </DrawerBody>
        </OverlayDrawer>
    }.into_any()
}

#[component]
pub fn OrderFliterList(
    /// 要显示的列
    #[prop(into)]
    tree_items: StoredValue<TreeItems>,
) -> impl IntoView {
    let table_state =
        use_context::<ReadSignal<TableState>>().expect("ReadSignal<TableState>在上下文中不存在");
    let get_label = move |name: &str| {
        let label = tree_items.with_value(|tis| tis.get_label(name).map(|v| v.to_owned()));
        label.unwrap_or("".to_owned())
    };
    let show_model = table_state.with_untracked(|ts| ts.show_order_filter_model());
    let ords = Memo::new(move |_| {
        table_state.with_untracked(|ts| {
            ts.order_cols
                .iter()
                .filter(|(_, c)| c.with(|c| c.is_some()))
                .map(|(name, c)| c.with(|o| (name.clone(), get_label(name), o.clone().unwrap())))
                .collect::<Vec<(_, _, _)>>()
        })
    });
    let ords_view = move || {
        ords.with(|ords|{
            if ords.is_empty(){
                return None
            }else{
                let ords=ords.clone();
                let ov=view!{
                    <div class="divider">排序</div>
                    <ul class="menu rounded-box max-h-64 overflow-auto">
                       {
                            ords.into_iter().map(|(name, label, ord)| view!{
                                <li>
                                    <div class="flex space-x-2">
                                        <div>{label}</div>
                                        <div>{ord.to_string()}</div>
                                        <div on:click=move|_|table_state.with_untracked(|ts|ts.set_order(&name, None))>
                                            <Icon icon=i::FiDelete/>
                                        </div>
                                    </div>
                                </li>
                            }).collect_view()
                       }
                    </ul>
                    <div class="flex justify-center mb-2">
                        <button class="btn btn-neutral btn-sm" on:click=move|_|table_state.with_untracked(|ts|ts.clear_all_orders())>清除排序</button>
                    </div>
                };
                Some(ov)
            }
        })
    };
    let filters = Memo::new(move |_| {
        table_state.with_untracked(|ts| {
            let fs = ts
                .filter_cols
                .iter()
                .filter(|(n, c)| c.with(|c| c.is_some()) && !ts.limit_filters.contains(*n))
                .map(|(name, c)| {
                    c.with(|f| {
                        (
                            name.clone(),
                            get_label(name),
                            f.as_ref().unwrap().to_string(),
                        )
                    })
                })
                .collect::<Vec<(_, _, _)>>();
            fs
        })
    });
    let filters_view = move || {
        let fs = filters.get();
        if fs.is_empty() {
            return None;
        } else {
            let fs = fs.clone();
            let ov = view! {
                <div class="divider">过滤</div>
                <ul class="menu rounded-box max-h-64 overflow-auto">
                    {
                        fs.into_iter().map(|(name, label, wc)| view!{
                            <li>
                                <div class="flex space-x-1">
                                    <div class="whitespace-nowrap text-ellipsis overflow-hidden max-w-24">{label}</div>
                                    <div class="grow whitespace-nowrap text-ellipsis overflow-hidden max-w-48">{wc}</div>
                                    <div on:click=move|_|table_state.with_untracked(|ts|ts.set_filter(&name, None))>
                                        <Icon icon=i::FiDelete/>
                                    </div>
                                </div>
                            </li>
                        }).collect_view()
                    }
                </ul>
                <div class="flex justify-center mb-2">
                    <button class="btn btn btn-neutral btn-sm" on:click=move|_|table_state.with_untracked(|ts|{
                        ts.clear_all_filters();
                        ts.set_show_order_filter_model(false);
                    })>清除过滤</button>
                </div>
            };
            Some(ov)
        }
    };
    view! {
        <Show when=move|| show_model.get()
             fallback=|| view! {}>
            <dialog class="modal modal-open">
                <div class="modal-box">
                    <header class="flex justify-between items-center">
                        <h3 class="text-lg font-bold">排序和过滤</h3>
                        <button class="btn btn-sm btn-circle"
                                on:click=move |_| show_model.set(false)>
                            <Icon icon=i::AiCloseCircleOutlined/>
                        </button>
                    </header>
                    <div class="card-body">
                        <div class="flex flex-col gap-2 h-full w-full">
                            <div class="flex-none bg-base-100 rounded-box">
                                {ords_view}
                            </div>
                            <div class="flex-1 bg-base-100 rounded-box">
                                {filters_view}
                            </div>
                        </div>
                    </div>
                </div>
            </dialog>
        </Show>
    }
    .into_any()
}
